#pragma once
#include "Socket.hpp"
#include <pthread.h>
#include <iostream>
#include <functional>

using func_t = std::function<std::string(std::string &)>;
class TcpServer;
class ThreadData
{
public:
    ThreadData() {}
    // ThreadData(TcpServer* this, Socket* sock)   //不能用this
    //     :_this(this), _sock(sock)
    // {}
    ThreadData(TcpServer *ptr, Socket *sock) //
        : _this(ptr), _sock(sock)
    {
    }

public:
    TcpServer *_this; // 为了回调的
    Socket *_sock;    // 为了通信
};
class TcpServer
{
public:
    TcpServer(uint16_t port, func_t func)
        : _port(port), _listensock(new TcpSocket()), _handler_request(func)
    {
        _listensock->CreateListenSocket(_port);
    }
    static void *ThreadRoutine(void *args)
    {
        pthread_detach(pthread_self());
        ThreadData *data = static_cast<ThreadData *>(args);
        // 1.收package，
        std::string packages;
        while (true)
        {
            // 1.将输入缓冲区中的数据读出来

            std::string part_package = data->_sock->Recv(); // 存放的是一个package的集合        //里面不对
            packages += part_package;

            // 2. 处理数据
            std::string response_package = data->_this->_handler_request(packages);
            // 3.发送response_package
            if (!data->_sock->Send(response_package))
                break; // 发失败也可以break
            std::cout << "-------" << std::endl;
        }

        delete data->_sock;
        delete data;
        return nullptr;
    }
    void Start()
    {
        while (true)
        {
            std::string clientip;
            uint16_t clientport;
            Socket *sockfd = _listensock->AcceptConnection(clientip, clientport);
            if (sockfd == nullptr)
                continue;

            pthread_t tid;
            // ThreadData data(this, sockfd);  //这样好像有bug，data好像直接没释放了
            ThreadData *data = new ThreadData(this, sockfd); // 这样好像有bug，data好像直接没释放了
            pthread_create(&tid, nullptr, ThreadRoutine, data);
        }
    }
    ~TcpServer()
    {
    }

private:
    int _port;
    Socket *_listensock;

public:
    func_t _handler_request;
};